package com.mo.axion.common.pipeline;

import com.mo.axion.common.enums.RespStatusEnum;
import com.mo.axion.common.vo.BasicResultVO;
import lombok.Data;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author Mo
 * @createTime 2024/2/1 14:33
 * @description 流程控制器
 */
@Data
public class ProcessController {
    /**
     * 模板映射
     */
    private Map<String, ProcessTemplate> templateConfig = null;

    /**
     * 执行责任链
     * @param context 上下文
     * @return 返回流程上下文
     */
    public ProcessContext process(ProcessContext context) {
        try {
            preCheck(context);
        } catch (ProcessException e) {
            return e.getProcessContext();
        }
        //  遍历请求处理流程节点
        List<BusinessProcess> processList = templateConfig.get(context.getCode()).getProcessList();
        for (BusinessProcess businessProcess : processList) {
            businessProcess.process(context);
            //  若需要中止 在此中止
            if (context.getIsNeedBreak()) {
                break;
            }
        }
        return context;
    }

    /**
     * 对上下文进行预检查
     * @param context
     * @throws ProcessException
     */
    private void preCheck(ProcessContext context) throws ProcessException {
        // 上下文检查
        if (Objects.isNull(context)) {
            context = new ProcessContext();
            context.setResponse(BasicResultVO.fail(RespStatusEnum.CONTEXT_IS_NULL));
            throw new ProcessException(context);
        }
        // 业务代码检查
        String businessCode = context.getCode();
        if (Objects.isNull(businessCode)) {
            context.setResponse(BasicResultVO.fail(RespStatusEnum.BUSINESS_CODE_IS_NULL));
            throw new ProcessException(context);
        }

        // 执行模板检查
        ProcessTemplate processTemplate = templateConfig.get(businessCode);
        if (Objects.isNull(processTemplate)) {
            context.setResponse(BasicResultVO.fail(RespStatusEnum.PROCESS_TEMPLATE_IS_NULL));
            throw new ProcessException(context);
        }

        // 执行模板列表
        List<BusinessProcess> processList = processTemplate.getProcessList();
        if (Objects.isNull(processList) || processList.size() == 0) {
            context.setResponse(BasicResultVO.fail(RespStatusEnum.PROCESS_LIST_IS_NULL));
            throw new ProcessException(context);
        }
    }
}
